#include "BufferNotifier.h"
#include <stdio.h>
#include <string.h>
#include <thread>
#include <unistd.h>

typedef struct frame_s_
{
    char* data;
    int len;
}frame_s;

class TestListener1 : public BufferListener
{
public:
    TestListener1();
    ~TestListener1();
    void dataCallback(const void *data);
    void setImporter(Importer* importer) { mImporter = importer; };
    void processFrame(void* frame_data);
private:
    Importer* mImporter;
};

TestListener1::TestListener1()
{

}

TestListener1::~TestListener1()
{

}

void TestListener1::dataCallback(const void *data)
{
    usrFrame* frame = (usrFrame*)data;
    std::thread([=] {
        processFrame(frame->frame_data);
        sleep(1);
        mImporter->releaseFrame(frame->frame_id);
    }).detach();
}

void TestListener1::processFrame(void* frame_data)
{
    frame_s* frame = (frame_s*)frame_data;
    printf("TestListener1 receive frame_data: %s, len: %d\n", (char*)frame->data, frame->len);
}

class TestListener2 : public BufferListener
{
public:
    TestListener2();
    ~TestListener2();
    void dataCallback(const void *data);
    void setImporter(Importer* importer) { mImporter = importer; };
    void processFrame(void* frame_data);
private:
    Importer* mImporter;
};

TestListener2::TestListener2()
{

}

TestListener2::~TestListener2()
{

}

void TestListener2::dataCallback(const void *data)
{
    usrFrame* frame = (usrFrame*)data;
    processFrame(frame->frame_data);
    mImporter->releaseFrame(frame->frame_id);
}

void TestListener2::processFrame(void* frame_data)
{
    frame_s* frame = (frame_s*)frame_data;
    printf("TestListener2 receive frame_data: %s, len: %d\n", (char*)frame->data, frame->len);
}

class TestImporter : public Importer
{
public:
    TestImporter();
    ~TestImporter();
    int onReleaseData(void* frame_data);
private:
};

int TestImporter::onReleaseData(void *frame_data)
{
    printf("importer release frame: %p\n", frame_data);
    frame_s* uframe = (frame_s*)frame_data;
    delete uframe->data;
    delete uframe;
    return 0;
}

TestImporter::TestImporter()
{

}

TestImporter::~TestImporter()
{

}

int main(int argc, char *argv[])
{
    TestImporter* mPorter = new TestImporter();
    TestListener1* Listener1 = new TestListener1();
    TestListener2* Listener2 = new TestListener2();
    Listener1->setImporter(mPorter);
    Listener2->setImporter(mPorter);
    mPorter->addListener(Listener1);
    mPorter->addListener(Listener2);

    {
        frame_s *pframe1 = new frame_s;
        printf("new frame_s: %p\n", pframe1);
        pframe1->data = new char[1024];
        strcpy(pframe1->data, "hello world1");
        pframe1->len = strlen(pframe1->data);
        mPorter->InputFrame((void*)pframe1);

        frame_s *pframe2 = new frame_s;
        printf("new frame_s: %p\n", pframe2);
        pframe2->data = new char[1024];
        strcpy(pframe2->data, "hello world2");
        pframe2->len = strlen(pframe2->data);
        mPorter->InputFrame((void*)pframe2);
    }
    sleep(5);

    return 0;
}